iT邦幫忙

2021 iThome 鐵人賽

DAY 12
0
Mobile Development

Flutter - 從 Packages & Plugins 掌握原生系列 第 12

Day12 開發插件 - 範例程式碼介紹01 Flutter 端

  • 分享至 

  • xImage
  •  

官方推薦的做法是使用cmd 來創建,可以去官方文件參考,這邊我來用Android Studio 來開發插件,以做一個獲得設備電池電量資訊的插件示範,順便對Flutter 的三種Platform Channel 做些實作範例

首先在Android Studio 上新增Flutter 專案

https://ithelp.ithome.com.tw/upload/images/20210927/201184796YEpLtGioI.png

選擇Plugin 後按下一步

https://ithelp.ithome.com.tw/upload/images/20210927/20118479BAfH9lRfGW.png

輸入您的專案名稱後,選擇要使用的平台原生程式語言後完成

https://ithelp.ithome.com.tw/upload/images/20210927/20118479WrB5qJnyNL.png

建立完成後我們來看看整個plugin 項目的結構

https://ithelp.ithome.com.tw/upload/images/20210927/201184797m9XJtPL0B.png

這邊我們先介紹其中幾個內容:

  • lib
    這是plugin package 中,Dart API 的程式碼,主要為了API 的功能實現,建立專案時會自動生成一個以專案名稱命名的.dart,供使用者在自己的flutter 專案中調用的接口代碼

  • android

    負責實現plugin package 中的Android 平台的功能實現,會與lib裡的接口配合進行功能開發

  • ios

    負責實現plugin package 中的iOS 平台的功能實現,會與lib裡的接口配合進行功能開發

  • example

    這是用來說明使用者如何在自己的flutter 專案中使用plugin package 的範例專案,此專案已經依賴我們的plugin package

MethodChannel

其中Android Studio 在建立時,就會生成一個用MethodChannel來獲取平台現在的版本的功能實現範例,我們先來看看是怎麼實現這個功能的

首先我們來看Flutter 端:

lib/batterylevel.dart

class Batterylevel {
  static const MethodChannel _channel =
      const MethodChannel('batterylevel');

  static Future<String> get platformVersion async {
    final String version = await _channel.invokeMethod('getPlatformVersion');
    return version;
  }
}

預設已在Flutter 端建立MethodChannel來呼叫Native 端的方法(預設MethodChannel 的名稱為專案名,且使用的所有通道名稱都不能重複),其通道的兩端,Native 端和Flutter 端會通過這個MethodChannel進行連接(故兩端使用的MethodChannel名稱需要相對應)

接下來預設建立的還有platformVersiongetter,會以非同步方式來對MethodChannel呼叫invokeMethod方法並傳入方法名來呼叫原生端對應的方法以獲取平台版本資訊

接著來看Native 端(Android):

預設建立的android/.../BatterylevelPlugin.kt

class BatterylevelPlugin: FlutterPlugin, MethodCallHandler {
  /// The MethodChannel that will the communication between Flutter and native Android
  ///
  /// This local reference serves to register the plugin with the Flutter Engine and unregister it
  /// when the Flutter Engine is detached from the Activity
  private lateinit var channel : MethodChannel

  override fun onAttachedToEngine(@NonNull flutterPluginBinding: FlutterPlugin.FlutterPluginBinding) {
    channel = MethodChannel(flutterPluginBinding.binaryMessenger, "batterylevel")
    channel.setMethodCallHandler(this)
  }

  override fun onMethodCall(@NonNull call: MethodCall, @NonNull result: Result) {
    if (call.method == "getPlatformVersion") {
      result.success("Android ${android.os.Build.VERSION.RELEASE}")
    } else {
      result.notImplemented()
    }
  }

  override fun onDetachedFromEngine(@NonNull binding: FlutterPlugin.FlutterPluginBinding) {
    channel.setMethodCallHandler(null)
  }
}

這邊用來實現Native 端(Android)的功能,首先會實作**FlutterPluginMethodCallHandler**接口

  1. 實作FlutterPlugin接口,必須實作onAttachedToEngine以及onDetachedFromEngine方法
    • onAttachedToEngine:插件被FlutterEngine加載時調用,可以做一些初始化工作,預設已在這邊設置好MethodChannel的通道名稱(需要與Flutter 端使用的MethodChannel名稱相對應),並通過MethodChannel呼叫setMethodCallHandler來註冊一個MessageHandler來接收此通道訊息,設定為this是因為BatterylevelPlugin已實作MethodCallHandler接口,所以能夠處理接收通道的訊息
    • onDetachedFromEngine:插件從FlutterEngine移除時調用,可以做一些清理工作,這邊對MethodChannel呼叫setMethodCallHandler設定為null,將此通道進行註銷
  2. 實作MethodCallHandler接口,就必須實作onMethodCall,目的可讓MethodChannel調用setMethodCallHandler,實現從Flutter 端要調用的原生方法,這邊對Flutter 端呼叫的方法getPlatformVersion做功能的實現,當Flutter 端呼叫此方法,就會回傳現在Android 的版本資訊回去

上一篇
Day11 Platform Channel - EventChannel
下一篇
Day13 開發套件 - 範例程式碼介紹02 Android 端
系列文
Flutter - 從 Packages & Plugins 掌握原生30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言